根據TheMealDB API的List all meal categories可看到有很多餐點分類,不過這次用到那麼多分類,所以等下會在data中定義會用到的餐點分類。
父組件MenusDetails.vue
<script>
export default{
data(){
return{
mealCategory:[],
categories:[
{type:'starter'},
{type:'chicken'},
{type:'beef'},
{type:'pork'},
{type:'seafood'},
{type:'pasta'},
{type:'lamb'},
{type:'goat'},
{type:'dessert'}
]
}
},
created(){
this.getMealData(this.categories[8]);
},
methods:{
//get category data
async getMealData(category){
const dataUrl = `https://www.themealdb.com/api/json/v1/1/filter.php?c=${category.type}`;
try{
const response = await fetch(dataUrl);
const data = await response.json();
this.mealCategory = data.meals;
}catch(e){
console.log(e);
}
},
menuName(category){
this.getMealData(category);
}
}
}
</script>
1.fetch API:https://developer.mozilla.org/en-US/docs/Web/API/Fetch_API/Using_Fetch
https://devhints.io/js-fetch
2.Async/Await:https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Statements/async_function
https://javascript.info/async-await
https://dmitripavlutin.com/javascript-fetch-async-await/
然後使用v-for在HTML中渲染出畫面
<!-- menus details -->
<div class="menusdetails__content">
<div class="row">
<div class="col-1-of-3" v-for="meal in mealCategory" :key="meal.index">
<div class="card">
<div class="card__side">
<div class="card__img-box">
<img :src=meal.strMealThumb alt="">
</div>
<h4 class="card__heading">
<span class="card__heading-span">
{{meal.strMeal}}
</span>
</h4>
<div class="card__cta">
<a href="javascript:void(0);" :data-id=meal.idMeal class="btn btn--2" @click="getMealDetails($event)">get details</a>
</div>
</div>
</div>
</div>
</div>
</div>
將get details按鈕利用HTML5的自定義屬性綁定每道餐點的id,讓用戶點進去後可看到餐點的詳細材料,這邊使用getMealDetails($event)方法根據每道餐點的id串接餐點材料的API
<script>
export default{
data(){
return{
mealDetails:[],
}
},
methods:{
async getMealDetails(e){
let id = e.target.getAttribute('data-id');
const dataUrl = `https://www.themealdb.com/api/json/v1/1/lookup.php?i=${id}`;
try{
const response = await fetch(dataUrl);
const data = await response.json();
this.mealDetails = data.meals;
}catch(e){
console.log(e);
}
}
}
}
</script>
再將mealDetails的資料傳到子組件Popup.vue即可
<template>
...
<Popup :details="mealDetails"></Popup>
</template>
子組件Popup.vue
先在props設定接收父組件的details數據為Array,然後使用computed處理一下mealDetails資料裡的strIngredient數據
<script>
export default {
props:{
details:Array
},
computed:{
getIngredients(){
//console.log(this.details['strIngredient1'])
return this.details.map(el => {
//console.log(el.strIngredient1)
let result = [];
for(let i=1;i<=30;i++){
if(el[`strIngredient${i}`] == ''){
break;
}
result.push(el[`strIngredient${i}`]);
}
return result;
})
}
}
}
</script>
然後一樣使用v-for在HTML上渲染出頁面
<div class="popup__dialog" v-for="detail in details" :key="detail.id">
<a href="#" class="popup__close" @click="closePopup">×</a>
<div class="popup__box">
<div class="popup__logobox">
<img class="popup__logo" :src=detail.strMealThumb :alt=detail.strMeal>
</div>
<div class="popup__text">
<h1 class="popup__heading">
{{detail.strMeal}}
</h1>
<h1 class="popup__heading">
Area:{{detail.strArea}}
</h1>
<h1 class="popup__heading">
Ingredient:
</h1>
<h1 class="popup__heading">
<p class="popup__heading" v-for="ingredient in getIngredients" :key="ingredient.index">
{{ingredient.toString()}}
</p>
</h1>
</div>
</div>
</div>
1.HTML5中的資料屬性:https://developer.mozilla.org/en-US/docs/Learn/HTML/Howto/Use_data_attributes
https://pjchender.blogspot.com/2017/01/html-5-data-attribute.html
2.Array.prototype.map():https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/map
參考資料:
1.TheMealDB API:https://www.themealdb.com/api.php
2.meal-search-api-vanilla-js:https://github.com/prabinmagar/meal-search-api-vanilla-js
3.Recipe-Catalogue:https://github.com/ampaire/Recipe-Catalogue